#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "defs.h"
#include "utils.h"
#include "setup.h"
#include "help.h"
#include "operator.h"

void operator_setup(struct hard_setup *hardware, struct soft_setup *software, struct gcode_setup *gcode)
{
   float value;
   int ch, curnt=0, i;
   static char item[9][35], screen[2000];

   gettext(21,1,60,25,screen);
   while(1)
     {window(21,1,60,25);
      textbackground(CYAN);
      clrscr();
      box(21,1,60,13, CYAN,BLACK,WHITE,BLACK);
      window(21,1,60,25);
      gotoxy(15,1); cprintf("<Esc> To Exit");
      sprintf(item[0],"Coordinate Offsets");
      sprintf(item[1],"Tool Table                        ");
      if((*software).units==IN)
        {sprintf(item[2],"<X> Tool Change Pos. (IN) %s",prn_val_all((*gcode).tool_ch_x));
         sprintf(item[3],"<Y> Tool Change Pos. (IN) %s",prn_val_all((*gcode).tool_ch_y));
         sprintf(item[4],"<Z> Tool Change Pos. (IN) %s",prn_val_all((*gcode).tool_ch_z));
         sprintf(item[8],"Units                           IN");
        }
      else
        {sprintf(item[2],"<X> Tool Change Pos. (MM) %s",prn_val_all((*gcode).tool_ch_x));
         sprintf(item[3],"<Y> Tool Change Pos. (MM) %s",prn_val_all((*gcode).tool_ch_y));
         sprintf(item[4],"<Z> Tool Change Pos. (MM) %s",prn_val_all((*gcode).tool_ch_z));
         sprintf(item[8],"Units                           MM");
        }
      if((*software).a_units==IN) sprintf(item[5],"<Aux> Tool Ch. Pos. (IN)  %s",prn_val_all((*gcode).tool_ch_a));
      if((*software).a_units==MM) sprintf(item[5],"<Aux> Tool Ch. Pos. (MM)  %s",prn_val_all((*gcode).tool_ch_a));
      if((*software).a_units==DEG) sprintf(item[5],"<Aux> Tool Ch. Pos. (DEG) %s",prn_val_all((*gcode).tool_ch_a));
      if((*software).a_units==RAD) sprintf(item[5],"<Aux> Tool Ch. Pos. (RAD) %s",prn_val_all((*gcode).tool_ch_a));

      if((*gcode).safer==ON)  sprintf(item[6],"G0 Movement         LINEAR (SAFER)");
      else sprintf(item[6],"G0 Movement    NON-LINEAR (FASTER)");
      if((*gcode).relarc==ON) sprintf(item[7],"I And J Always Relative         ON");
      else sprintf(item[7],"I And J Always Relative        OFF");
      for(i=0;i<9;i++) {gotoxy(4,i+3); cprintf("%s",item[i]);}
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+3); textbackground(BLUE);
         cprintf("%s",item[curnt]); ch=getch();
         textcolor(BLACK); gotoxy(4,curnt+3); textbackground(CYAN);
         cprintf("%s",item[curnt]);
         if (ch == 13 || ch == 32)
           {gotoxy(4,curnt+3); textbackground(GREEN);
            cprintf("%s",item[curnt]); textbackground(CYAN);
            break;
           }
         if (ch == 27) {puttext(21,1,60,25,screen); return;}
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 59 :  //f1
              switch(curnt)
                {case 0: help(43); break;
                 case 1: help(44); break;
                 case 2: case 3: case 4: case 5: help(45); break;
                 case 6: help(46); break;
                 case 7: help(48); break;
                 case 8: help(47); break;
                }
              break;
           }
         if (curnt < 0) curnt=8;
         if (curnt > 8) curnt=0;
        }

      switch(curnt)
        {case 0: offsets(gcode); break;
         case 1: tools(gcode); break;
         case 2:
         case 3:
         case 4:
         case 5:
            double_box(30,15,50,20, BLUE,WHITE,WHITE);
            gotoxy(4,3); cprintf("Enter New Value");
            _setcursortype(_NORMALCURSOR);
            gotoxy(8,4);
            if((i=get_value_all(&value))==ESC || i==NULL)
              {_setcursortype(_NOCURSOR);
               clrscr();
               window(21,1,60,25);
               break;
              }
            _setcursortype(_NOCURSOR);
            clrscr();
            window(21,1,60,25);
            if(curnt==2) (*gcode).tool_ch_x=value;
            if(curnt==3) (*gcode).tool_ch_y=value;
            if(curnt==4) (*gcode).tool_ch_z=value;
            if(curnt==5) (*gcode).tool_ch_a=value;
            break;
         case 6:
            if((*gcode).safer==ON) (*gcode).safer=OFF;
            else (*gcode).safer=ON;
            break;
         case 7:
            if((*gcode).relarc==ON) (*gcode).relarc=OFF;
            else (*gcode).relarc=ON;
            break;
         case 8:
            if((*software).units==MM)
              {change_gcode_units(software, gcode, IN, IN);
               change_units(hardware, software, IN, IN);
              }
            else
              {change_gcode_units(software, gcode, MM, MM);
               change_units(hardware, software, MM, MM);
              }
            break;
        }
     }
}

void tools(struct gcode_setup *gcode)
{
   int curnt=1, page=0, i;
   float temp_dia, temp_len;
   char temp_dis[10], ch, temp_val[10];

   window(21,1,60,25); textbackground(CYAN); clrscr();
   gotoxy(4,1); textcolor(BLACK); cprintf("<Enter> To Edit Or <Esc> To Exit");
   box(21,3,60,25, CYAN,BLACK,WHITE,BLACK);
   while (1)
     {box(21,3,60,25, CYAN,BLACK,WHITE,CYAN);

      textbackground(BLUE); textcolor(WHITE);
      gotoxy(3,3); cprintf("Tool#   Desc.   Diameter     Length ");

      textcolor(BLACK); textbackground(CYAN);
      gotoxy(4,1); cprintf("Current Tool: %2d",(*gcode).tnum);
      if(curnt==17) {page++; curnt=0;}
      else if(curnt==0 && page>0) {page--; curnt=17;}
      if(page==0)
        {for(i=0;i<17;i++)
           {gotoxy(4,i+4);
            sprintf(temp_val,"%s",prn_val((*gcode).tool_len[i]));
            cprintf("%2d  %8s    %s    %s",i,(*gcode).tool_dis[i],
                    prn_val((*gcode).tool_dia[i]),temp_val);
           }
         if( maxtoolsplusone >(page+1)*16+1) {gotoxy(4,i+4); cprintf("More Tools...");}
        }
      else
        {gotoxy(4,4); cprintf("Previous Tools...");
         for(i=0;i<min(maxtools-page*16,16);i++)
           {gotoxy(4,i+5);
            sprintf(temp_val,"%s",prn_val((*gcode).tool_len[page*16+1+i]));
            cprintf("%2d  %8s    %s    %s",page*16+1+i,(*gcode).tool_dis[page*16+1+i],
                    prn_val((*gcode).tool_dia[page*16+1+i]),temp_val);

           }
         if( maxtoolsplusone>(page+1)*16+1) {gotoxy(4,i+5); cprintf("More Tools...");}
        }
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+4); textbackground(BLUE);
         if(curnt==17) cprintf("More Tools...");
         else if(curnt==0 && page!=0) cprintf("Previous Tools...");
         else
           {sprintf(temp_val,"%s",prn_val((*gcode).tool_len[page*16+curnt]));
            cprintf("%2d  %8s    %s    %s",page*16+curnt,(*gcode).tool_dis[page*16+curnt],
                    prn_val((*gcode).tool_dia[page*16+curnt]),temp_val);
           }
         ch=getch();
         gotoxy(4,curnt+4); textbackground(CYAN); textcolor(BLACK);
         if(curnt==17) cprintf("More Tools...");
         else if(curnt==0 && page!=0) cprintf("Previous Tools...");
         else
           {sprintf(temp_val,"%s",prn_val((*gcode).tool_len[page*16+curnt]));
                    cprintf("%2d  %8s    %s    %s",page*16+curnt,(*gcode).tool_dis[page*16+curnt],
                    prn_val((*gcode).tool_dia[page*16+curnt]),temp_val);}
         if ((ch==13 || ch==32) && curnt!=0 && curnt!=17)
           {if(page*17+curnt==(*gcode).tnum)
              {box(22,19,59,24, RED,BLACK,WHITE,WHITE);
               gotoxy(4,3); cprintf("    Can't Edit Current Tool");
               gotoxy(4,4); cprintf("           <Any Key>");
               getch();
               break;
              }
            gotoxy(4,curnt+4); textbackground(GREEN);
            sprintf(temp_val,"%s",prn_val((*gcode).tool_len[page*16+curnt]));
            cprintf("%2d  %8s    %s    %s",page*16+curnt,(*gcode).tool_dis[page*16+curnt],
            prn_val((*gcode).tool_dia[page*16+curnt]),temp_val);
            box(22,19,59,24, BLUE,BLACK,WHITE,WHITE);
            gotoxy(2,1); cprintf("           <Esc> To Abort");
            gotoxy(4,3); cprintf("Tool#: %2d  Description:",page*16+curnt);
            gotoxy(4,4); cprintf("Dia.:");
            gotoxy(20,4); cprintf("Length:");
            _setcursortype(_NORMALCURSOR); temp_dia=temp_len=0; sprintf(temp_dis,"NONE");
            gotoxy(28,3); if(ESC==get_string_all(temp_dis)) {_setcursortype(_NOCURSOR); break;}
            gotoxy(10,4); if(ESC==get_value(&temp_dia)) {_setcursortype(_NOCURSOR); break;}
            gotoxy(28,4); if(ESC==get_value(&temp_len)) {_setcursortype(_NOCURSOR); break;}
            _setcursortype(_NOCURSOR);
            sprintf((*gcode).tool_dis[page*16+curnt],"%s",temp_dis);
            (*gcode).tool_dia[page*16+curnt]=temp_dia;
            (*gcode).tool_len[page*16+curnt]=temp_len;
            (*gcode).tnum_max=(*gcode).tnum_max+1;
            break;
           }
         if (ch==27 || ch==13 || ch==32) break;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 81 : if (page<(maxtools/16)) curnt=17;
            				break;  //pg dn
            case 73 : if (page==0) curnt=1;
            			 else if (page >0) curnt=0;
                      break;   // pg up
            case 59 : help(53); break;
           }
         if (ch==27) {ch=0; break;}
			if (curnt < 1 && page == 0) curnt=1;
         if (curnt <0) curnt=0;

//         if (curnt > min(maxtools-(16*page),17)) {if(page==0) curnt=1; else curnt=0;}
//			if (curnt >17) curnt=17;
         if ((page == maxpage) && (curnt > 7)) curnt= 7 ;
			if (curnt>17) curnt=17;
        }
      if(ch==27) break;
     }
}

void offsets(struct gcode_setup *gcode)
{
   int i, curnt=0, ch;
   static char item[7][35]={"Machine Coordinates (G53)","Coordinate Offset 2 (G54)",
                            "Coordinate Offset 3 (G55)","Coordinate Offset 4 (G56)",
                            "Coordinate Offset 5 (G57)","Coordinate Offset 6 (G58)",
                            "Coordinate Offset 7 (G59)"};
   while(1)
     {window(21,1,60,25);
      textbackground(CYAN);
      clrscr();
      box(21,1,60,11, CYAN,BLACK,WHITE,BLACK);
      window(21,1,60,25);
      gotoxy(15,1); cprintf("<Esc> To Exit");
      for(i=0;i<7;i++) {gotoxy(4,i+3); cprintf("%s",item[i]);}
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+3); textbackground(BLUE);
         cprintf("%s",item[curnt]); ch=getch();
         textcolor(BLACK); gotoxy(4,curnt+3); textbackground(CYAN);
         cprintf("%s",item[curnt]);
         if (ch == 13 || ch == 32)
           {gotoxy(4,curnt+3); textbackground(GREEN); cprintf("%s",item[curnt]); break;}
         if (ch == 27) return;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 81 : curnt=6; break;  //pgdn
            case 73 : curnt=0; break;  //pgup
            case 59 : help(54); break;  //f1
           }
         if (curnt < 0) curnt=0;
         if (curnt > 6) curnt=6;
        }
      box(22,16,59,24, BLUE,BLACK,WHITE,WHITE);
      gotoxy(2,1); cprintf("            <Esc> To Exit");
      if(curnt==0)
        {gotoxy(4,3); cprintf("Machine Coordinates");
         gotoxy(4,4); cprintf("X = %s", prn_val_all((*gcode).x_coord[curnt]));
         gotoxy(21,4); cprintf("Y = %s", prn_val_all((*gcode).y_coord[curnt]));
         gotoxy(4,5); cprintf("Z = %s", prn_val_all((*gcode).z_coord[curnt]));
         gotoxy(21,5); cprintf("W = %s", prn_val_all((*gcode).a_coord[curnt]));
        }
      else
        {gotoxy(4,3); cprintf("Coordinate Offset %d",curnt+1);
         gotoxy(4,4); cprintf("<X> -> %s", prn_val_all((*gcode).x_coord[curnt]));
         gotoxy(21,4); cprintf("<Y> -> %s", prn_val_all((*gcode).y_coord[curnt]));
         gotoxy(4,5); cprintf("<Z> -> %s", prn_val_all((*gcode).z_coord[curnt]));
         gotoxy(21,5); cprintf("<W> -> %s", prn_val_all((*gcode).a_coord[curnt]));
        }
      gotoxy(4,6); cprintf("<R> Z Release Plane %s", prn_val_all((*gcode).rp[curnt]));
      gotoxy(4,7); cprintf("<P> W Release Plane %s", prn_val_all((*gcode).a_rp[curnt]));
      while((i=getch())!=27)
        {if(i>96 && i<123) i=i-32;
         if((curnt>0 && (i=='X' || i=='Y' || i=='Z' || i=='W')) || i=='R' || i=='P')
           {_setcursortype(_NORMALCURSOR);
            gotoxy(6,9);
            if(i=='R') {cprintf("Z Release Plane Value:"); gotoxy(29,9);}
            else if(i=='P') {cprintf("W Release Plane Value:"); gotoxy(29,9);}
            else {cprintf("Enter New '%c' Value:",i); gotoxy(27,9);}
            if(i=='X') {get_value_all(&(*gcode).x_coord[curnt]);
                        gotoxy(4,4); cprintf("<X> -> %s", prn_val_all((*gcode).x_coord[curnt]));}
            if(i=='Y') {get_value_all(&(*gcode).y_coord[curnt]);
                        gotoxy(21,4); cprintf("<Y> -> %s", prn_val_all((*gcode).y_coord[curnt]));}
            if(i=='Z') {get_value_all(&(*gcode).z_coord[curnt]);
                        gotoxy(4,5); cprintf("<Z> -> %s", prn_val_all((*gcode).z_coord[curnt]));}
            if(i=='W') {get_value_all(&(*gcode).a_coord[curnt]);
                        gotoxy(21,5); cprintf("<W> -> %s", prn_val_all((*gcode).a_coord[curnt]));}
            if(i=='R') {get_value_all(&(*gcode).rp[curnt]);
                        gotoxy(4,6); cprintf("<R> Z Release Plane %s", prn_val_all((*gcode).rp[curnt]));}
            if(i=='P') {get_value_all(&(*gcode).a_rp[curnt]);
                        gotoxy(4,7); cprintf("<P> W Release Plane %s", prn_val_all((*gcode).a_rp[curnt]));}
            gotoxy(6,9); cprintf("                                "); _setcursortype(_NOCURSOR);
           }
        }
     }
}

void change_gcode_units(struct soft_setup *software, struct gcode_setup *gcode, int units, int a_units)
{
   int i;

   if((*software).units==IN && units==MM)
     {for(i=0;i<7;i++)
        {(*gcode).x_coord[i]=(*gcode).x_coord[i]*25.4;
         (*gcode).y_coord[i]=(*gcode).y_coord[i]*25.4;
         (*gcode).z_coord[i]=(*gcode).z_coord[i]*25.4;
         (*gcode).rp[i]=(*gcode).rp[i]*25.4;
        }
      for(i=0;i<=(*gcode).tnum_max;i++)
        {(*gcode).tool_len[i]=(*gcode).tool_len[i]*25.4;
         (*gcode).tool_dia[i]=(*gcode).tool_dia[i]*25.4;
        }
      (*gcode).tool_ch_x=(*gcode).tool_ch_x*25.4;
      (*gcode).tool_ch_y=(*gcode).tool_ch_y*25.4;
      (*gcode).tool_ch_z=(*gcode).tool_ch_z*25.4;
     }
   else if((*software).units==MM && units==IN)
     {for(i=0;i<7;i++)
        {(*gcode).x_coord[i]=(*gcode).x_coord[i]/25.4;
         (*gcode).y_coord[i]=(*gcode).y_coord[i]/25.4;
         (*gcode).z_coord[i]=(*gcode).z_coord[i]/25.4;
         (*gcode).rp[i]=(*gcode).rp[i]/25.4;
        }
      for(i=0;i<=(*gcode).tnum_max;i++)
        {(*gcode).tool_len[i]=(*gcode).tool_len[i]/25.4;
         (*gcode).tool_dia[i]=(*gcode).tool_dia[i]/25.4;
        }
      (*gcode).tool_ch_x=(*gcode).tool_ch_x/25.4;
      (*gcode).tool_ch_y=(*gcode).tool_ch_y/25.4;
      (*gcode).tool_ch_z=(*gcode).tool_ch_z/25.4;
     }
   if((*software).a_units==IN && a_units==MM)
     {for(i=0;i<7;i++)
        {(*gcode).a_coord[i]=(*gcode).a_coord[i]*25.4;
         (*gcode).a_rp[i]=(*gcode).a_rp[i]*25.4;
        }
      (*gcode).tool_ch_a=(*gcode).tool_ch_a*25.4;
     }
   else if((*software).a_units==MM && a_units==IN)
     {for(i=0;i<7;i++)
        {(*gcode).a_coord[i]=(*gcode).a_coord[i]/25.4;
         (*gcode).a_rp[i]=(*gcode).a_rp[i]/25.4;
        }
      (*gcode).tool_ch_a=(*gcode).tool_ch_a/25.4;
     }
   if((*software).a_units==DEG && a_units==RAD)
     {for(i=0;i<7;i++)
        {(*gcode).a_coord[i]=(*gcode).a_coord[i]/57.29578;
         (*gcode).a_rp[i]=(*gcode).a_rp[i]/57.29578;
        }
      (*gcode).tool_ch_a=(*gcode).tool_ch_a/57.29578;
     }
   else if((*software).a_units==RAD && a_units==DEG)
     {for(i=0;i<7;i++)
        {(*gcode).a_coord[i]=(*gcode).a_coord[i]*57.29578;
         (*gcode).a_rp[i]=(*gcode).a_rp[i]*57.29578;
        }
      (*gcode).tool_ch_a=(*gcode).tool_ch_a*57.29578;
     }
}

void load_gcode_setup(struct gcode_setup *gcode)
{
   int cancel=OFF, version=0, i;
   static struct gcode_setup temp_gcode;
   FILE *ifp;

   if(NULL==(ifp = fopen ("GCODE.INI","rb"))) cancel=ON;
   if(cancel==OFF) fscanf(ifp, "%d", &version);
   if(version==1)
     {if(NULL==fscanf(ifp, "%f",&temp_gcode.tool_ch_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",&temp_gcode.tool_ch_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",&temp_gcode.tool_ch_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",&temp_gcode.tool_ch_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",&temp_gcode.safer)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",&temp_gcode.relarc)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",&temp_gcode.tnum)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",&temp_gcode.tnum_max)) cancel=ON;
      temp_gcode.tnum_max=maxtools;
      for(i=0;i<7;i++)
        {if(NULL==fscanf(ifp, "%f",&temp_gcode.x_coord[i])) cancel=ON;
         if(NULL==fscanf(ifp, "%f",&temp_gcode.y_coord[i])) cancel=ON;
         if(NULL==fscanf(ifp, "%f",&temp_gcode.z_coord[i])) cancel=ON;
         if(NULL==fscanf(ifp, "%f",&temp_gcode.a_coord[i])) cancel=ON;
         if(NULL==fscanf(ifp, "%f",&temp_gcode.rp[i])) cancel=ON;
         if(NULL==fscanf(ifp, "%f",&temp_gcode.a_rp[i])) cancel=ON;
        }
      for(i=1;i<maxtoolsplusone;i++)
        {if(NULL==fscanf(ifp, "%s",&temp_gcode.tool_dis[i])) cancel=ON;
         if(NULL==fscanf(ifp, "%f",&temp_gcode.tool_dia[i])) cancel=ON;
         if(NULL==fscanf(ifp, "%f",&temp_gcode.tool_len[i])) cancel=ON;
        }
     }
   if(cancel==OFF) *gcode=temp_gcode;
   else (*gcode).relarc=ON;
   sprintf((*gcode).tool_dis[0],"NO TOOL");
   fclose(ifp);
}

void save_gcode_setup(struct gcode_setup *gcode)
{
   int i;
   FILE *ofp;

   ofp = fopen ("GCODE.INI","wb");
   fprintf(ofp, "1\n");   //version 1
   fprintf(ofp, "%f\n",(*gcode).tool_ch_x);
   fprintf(ofp, "%f\n",(*gcode).tool_ch_y);
   fprintf(ofp, "%f\n",(*gcode).tool_ch_z);
   fprintf(ofp, "%f\n",(*gcode).tool_ch_a);
   fprintf(ofp, "%d\n",(*gcode).safer);
   fprintf(ofp, "%d\n",(*gcode).relarc);
   fprintf(ofp, "%d\n",(*gcode).tnum);
   fprintf(ofp, "%d\n",(*gcode).tnum_max);
   for(i=0;i<7;i++)
     {fprintf(ofp, "%f\n",(*gcode).x_coord[i]);
      fprintf(ofp, "%f\n",(*gcode).y_coord[i]);
      fprintf(ofp, "%f\n",(*gcode).z_coord[i]);
      fprintf(ofp, "%f\n",(*gcode).a_coord[i]);
      fprintf(ofp, "%f\n",(*gcode).rp[i]);
      fprintf(ofp, "%f\n",(*gcode).a_rp[i]);
     }
   for(i=1;i<maxtoolsplusone;i++)
     {fprintf(ofp, "%s\n",(*gcode).tool_dis[i]);
      fprintf(ofp, "%f\n",(*gcode).tool_dia[i]);
      fprintf(ofp, "%f\n",(*gcode).tool_len[i]);
     }
   fclose(ofp);
}
